/**
 68 AD 00 AD 00 68 4B 03 41 2F F8 02 10 6A 00 00 01 01 01 00 01 11 10 11 10 00 00 00 01 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 7A 16
 68 71 00 71 00 68 4B 03 41 2F F8 02 0C 68 00 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 2E 16
 */
var Rango = {};

/** Trim
 */
String.prototype.trim = function() {
	var trimLeft = /^\s+/;
	var trimRight = /\s+$/;
  return this.toString().replace( trimLeft, "" ).replace( trimRight, "" );
};

/** 对数组中指定范围的数据进行反转、补零等操作，并返回去掉逗号的字符串，一般用来返回通讯地址
 */
Rango.Sort = function(frame, b, e, isBCD) {
  var str = '', arr = frame.slice(b, e).reverse();
  for (var i in arr) {
    str += Rango.Zerofill(arr[i].toString(16), 2);
  };
  return str;
};

/** 清除左右两边的内容
 */
Rango.FrameClear = function() {
  document.getElementById('frameBox').value = '';
  document.getElementById('result').innerHTML = '';
};

Rango.JSON2Table = function(json) {
  var table = '';
  for (var i in json) {
    table += '<tr><td align="right">' + json[i].name + '</td><td>' + json[i].value + '</td></tr>';
  };
  return '<table border="1">' + table + '</table>';
};

/** 补零
 */
Rango.Zerofill = function(str, len) {
  str = str.toString();
  var n = len - str.length;
  if (n < 1) return str;
  for (var i = 0; i < n; i++) 
    str = '0' + str;
  return str;
};

/** BCDtoB
 */
Rango.BCDtoB = function(bcdval) {
  return Math.floor((bcdval / 16)) * 10 + bcdval % 16;
};

/** 检查帧头
 */
Rango.checkFrameHead = function(frame) {
  return frame[0] == 0x68 && frame[5] == 0x68 && frame[1] == frame[3] && frame[2] == frame[4];
};

/** 检查帧尾
 */
Rango.checkFrameTail = function(frame) {
  return frame[frame.length - 1] == 0x16;
};

/** 返回帧AFN
 */
Rango.AFN = function(frame) {
  return frame[12];
};

/** 返回传输方向位DIR
 */
Rango.DIR = function(frame) {
  var dir = parseInt(Rango.Zerofill(frame[6].toString(2), 8).charAt(8-7-1));
  return dir ? 1 : 0;
};

/** 返回启动标志位PRM
 */
Rango.PRM = function(frame) {
  var prm  = parseInt(Rango.Zerofill(frame[6].toString(2), 8).charAt(8-6-1));
  return prm ? 1 : 0;
};

/** 由DA得到信息点Pn
 */
Rango.Pn = function(frame) {
  var i = 0, da1 = frame[14], da2 = frame[15];
  if(da1 == 0 && da2 == 0) return 0;
  while(da1 > 1) {
      i++;
      da1 = Math.floor(da1 / 2);
  }
  return (da2 - 1) * 8 + i + 1;
};

/** 返回帧Fn
 */
Rango.Fn = function(frame) {
  var i = 0, dt1 = frame[16], dt2 = frame[17];
  while (dt1 > 1) {
    i++;
    dt1 = Math.floor(dt1 / 2);
  };
  return dt2 * 8 + i + 1;
};

/** 返回行政区划码
 */
Rango.GetAreaCode = function(frame) {
  var code1 = Rango.Zerofill(Rango.BCDtoB(frame[8]).toString(), 2);
  var code2 = Rango.Zerofill(Rango.BCDtoB(frame[7]).toString(), 2);
  return code1 + code2;
};

/** 返回终端地址
 */
Rango.GetTermAdd = function(frame) {
  return parseInt('0x' + frame[10].toString(16) + frame[9].toString(16));
};

/** 检查帧校验和
 */
Rango.CheckCS = function(frame) {
  var cs = 0;
  for (var i = 6; i < frame.length - 2; i++)
    cs += frame[i];
  return cs % 256 == frame[frame.length - 2];
};

/** 检查帧的正确性
 */
Rango.CheckFrame = function(frame) {
  return Rango.checkFrameHead(frame) && Rango.checkFrameTail(frame) && Rango.CheckCS(frame);
};

/** 取得输入框中的字符串
 */
Rango.GetFrame = function() {
  var box = document.getElementById('frameBox');
  var tmpArr = box.value.split('\n'), frameArr = [];
  for(var i in tmpArr) {
    tmp = tmpArr[i].trim().split(' ');
    if (tmp[0].length > 2 || tmp == '') {
      continue;
    } else {
      for(var j in tmp) {
        tmp[j] = parseInt(tmp[j], 16);
      };
      frameArr.push(tmp);
    }
  }
  return frameArr;
};

/** 显示转换后的结果
 */
Rango.ShowResult = function(result) {
  var box = document.getElementById('result'), innerHTML = box.innerHTML;
  box.innerHTML += ('<li style="padding-bottom: 15px;">' + result);
};

/** 转换
 */
Rango.Translate = function() {
  var frameArr = Rango.GetFrame(), result;
  document.getElementById('result').innerHTML = '';
  for(var i in frameArr) {
    var frame = frameArr[i];
    if (Rango.CheckFrame(frame)) {
      var DIR = Rango.DIR(frame), PRM = Rango.PRM(frame) ? '来自启动站' : '来自从动站',
          AFN = Rango.AFN(frame), Fn = Rango.Fn(frame), Pn = Rango.Pn(frame),
          AreaCode = Rango.GetAreaCode(frame), TermAdd = Rango.GetTermAdd(frame);

      result = (DIR ? '上行报文' : '下行报文') + ', ' + (PRM ? '来自启动站' : '来自从动站') + ', 行政区划码 = ' + AreaCode + 
               ', 终端地址 = ' + TermAdd + ', AFN = 0x' + AFN.toString(16) + '(' + AFN +'), Fn = ' + Fn + ', Pn = ' + Pn + ';';
      result += '<p>' + Rango.DL698['AFN' + AFN]['Fn' + Fn](frame, DIR) || '' + '</p>';
    } else {
      result = '帧结构错误。';
    }
    Rango.ShowResult(result || '');
  }
};